#include<pthread.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#define BUFFZ_SIZE 10
//互斥锁
pthread_mutex_t mutex;
//条件变量，生产者条件变量
pthread_cond_t prod_cond;
//条件变量，消费者条件变量
pthread_cond_t cons_cond;

//环形数组
int buff[BUFFZ_SIZE];

//定义消费和生产索引
int in = 0;
int out = 0;

void * prod_func(void *){
    while(1){
        pthread_mutex_lock(&mutex);
        while(((in+1)%BUFFZ_SIZE) == out){
            printf("生产者队列满，挂起线程\n");
            pthread_cond_wait(&prod_cond, &mutex);
        }
        int num = rand()%100;
        printf("生产者向位置[%d]生产数据[%d]\n", in, num);
        buff[in]= num;
        in = (in+1)%BUFFZ_SIZE;    
        pthread_cond_signal(&cons_cond);
        pthread_mutex_unlock(&mutex);
        num = rand()%3;
        sleep(1);
    }

    return NULL;
}

void * cons_func(void *){
    while(1){
        pthread_mutex_lock(&mutex);
        while(in == out){
            printf("消费者队列空，挂起线程\n");
            pthread_cond_wait(&cons_cond, &mutex);
        }
        
        printf("消费者线程从位置[%d]消费数据[%d]\n", out, buff[out]);
        out = (out+1)%BUFFZ_SIZE;
        pthread_cond_signal(&prod_cond);
        pthread_mutex_unlock(&mutex);
        int num = rand()%3;
        sleep(3);
    }
    return NULL;
}


int main(){
    //初始化互斥锁
    pthread_mutex_init(&mutex,NULL);
    //初始化条件变量
    pthread_cond_init(&prod_cond,NULL);
    pthread_cond_init(&cons_cond,NULL);
    //设置随机因子
    srand(time(NULL));
    //创建生产者线程
    pthread_t pro_thread;
    int res = pthread_create(&pro_thread,NULL,(void*)prod_func,NULL);
    if(res){
        perror("pthread_create product error");
        exit(1);
    }

    //创建消费者线程
    pthread_t cons_thread;
    res = pthread_create(&cons_thread,NULL,(void*)cons_func,NULL);
    if(res){
        perror("pthread_create consumer error");
        exit(1);
    }

    pthread_join(pro_thread,NULL);
    pthread_join(cons_thread,NULL);

    //销毁互斥锁和条件变量
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&prod_cond);
    pthread_cond_destroy(&cons_cond);
    return 0;
}

